/**
  ******************************************************************************
  * @file    modbus_host.h
  * @author  ashuai0110
  * @version V2.4
  * @date    2024-09-10
  * @brief   modbus主机程序(RTU ASCII)
  *
  ******************************************************************************
  * @attention
  *
  * 版权声明:内容为编者(ashuai0110)原创,使用请注明出处,当然,你也可以不这样做^_^
  * 出处链接:https://gitee.com/ashuai0110/mcu_reuse_development_module.git
  *
  ******************************************************************************
  */

#ifndef __MODBUS_HOST_H
#define __MODBUS_HOST_H

#ifdef __cplusplus
extern "C" {
#endif

/* 包含头文件-----------------------------------------------------------------*/
#include "modbus_common.h"

/**
 * @addtogroup modbus
 * @{
 */

/**
 * @addtogroup modbus_host
 * @{
 */

/* 宏定义---------------------------------------------------------------------*/

/* 类型定义-------------------------------------------------------------------*/
/**
 * @defgroup modbus_host_global_types modbus host global types
 * @{
 */

/** 
  * @brief  modbus主机 structure definition
  */
typedef struct mb_host {
    uint8_t *dataBuf;         /*!< 数据缓存区 */
    uint16_t dataBufLen;      /*!< 数据缓存区长度 */
    uint16_t dataLen;         /*!< 数据长度 */
    uint16_t readLen;         /*!< 读出数据长度 */

    uint32_t targetFrameIntv; /*!< 目标帧间隔ms */
    uint32_t curFrameIntv;    /*!< 当前帧间隔temp */
    uint32_t rspTimeout;      /*!< 应答超时时间ms */
    uint32_t rspTimeoutCnt;   /*!< 应答超时计数temp */
    
    uint8_t protocol : 1;     /*!< 协议类型 @ref modbus_common_protocol */
    uint8_t state : 2;        /*!< 应答状态 @ref modbus_common_state */
    uint8_t broadcast : 1;    /*!< 广播标志 0:非广播 1:广播 */
    uint8_t slaveTmp;         /*!< 主机命令中的从机地址temp */
    uint16_t regTmp;          /*!< 主机命令中的起始地址temp */
    uint16_t numTmp;          /*!< 主机命令中的数量temp */

    modbus_tx_en_t txEnFn;    /*!< 主机发送前(串口)准备函数 */
} mb_host_t;

/**
 * @}
 */

/* 全局变量-------------------------------------------------------------------*/

/* 函数原型-------------------------------------------------------------------*/
/**
 * @addtogroup modbus_host_global_functions
 * @{
 */

void mb_host_init(mb_host_t *_mbh, uint8_t protocol, void *pBuf, uint16_t bufLen, modbus_tx_en_t txEnFn, uint32_t frameIntv, uint32_t rspTimeout);

uint8_t mb_host_poll(mb_host_t *_mbh);

uint8_t mb_host_send_cmd(mb_host_t *_mbh, uint8_t slaveAddr, uint8_t funCode, uint16_t reg, uint16_t num, void *extend);

uint16_t mb_host_write_rx_buf(mb_host_t *_mbh, void *pBuf, uint16_t len);
uint16_t mb_host_read_tx_buf(mb_host_t *_mbh, void *pBuf, uint16_t len);

/* set/get interface */
void mb_host_set_protocol(mb_host_t *_mbh, uint8_t protocol);
uint8_t mb_host_get_protocol(mb_host_t *_mbh);
void mb_host_set_frame_intv(mb_host_t *_mbh, uint32_t frameIntv);
uint32_t mb_host_get_frame_intv(mb_host_t *_mbh);
void mb_host_set_rsp_timeout(mb_host_t *_mbh, uint32_t timeout);
uint32_t mb_host_get_rsp_timeout(mb_host_t *_mbh);

/* 弱定义函数 */
void mb_host_rsp_01h(mb_host_t *_mbh, uint16_t reg, uint16_t num, uint8_t *pData);
void mb_host_rsp_02h(mb_host_t *_mbh, uint16_t reg, uint16_t num, uint8_t *pData);
void mb_host_rsp_03h(mb_host_t *_mbh, uint16_t reg, uint16_t num, uint8_t *pData);
void mb_host_rsp_04h(mb_host_t *_mbh, uint16_t reg, uint16_t num, uint8_t *pData);
void mb_host_rsp_05_10h(mb_host_t *_mbh);
void mb_host_rsp_err(mb_host_t *_mbh, uint8_t *pData);

/**
 * @}
 */

/**
 * @}
 */

/**
 * @}
 */

#ifdef __cplusplus
}
#endif

#endif /* modbus_host.h */
